/**
 *  Copyright (c)  2011-2020 Panguso, Inc.
 *  All rights reserved.
 *
 *  This software is the confidential and proprietary information of Panguso, 
 *  Inc. ("Confidential Information"). You shall not
 *  disclose such Confidential Information and shall use it only in
 *  accordance with the terms of the license agreement you entered into with Panguso.
 */


/*

 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cn.edu.thu.log.tree;

import cn.edu.thu.log.filter.logfilter.ReadContentByTagName;
import cn.edu.thu.log.filter.parameter.FilterParameter;
import cn.edu.thu.log.read.LogBufferModified;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import cn.edu.thu.log.web.service.PropertiesReaderServices;
import cn.edu.thu.log.web.service.impl.PropertiesReaderServicesImpl;
import storage.dbhelper.TreeFileHelper;

/**
 * 
 * @author wan
 */
public class CalculateTree {

	private Map<ManyTreeNode, Boolean> resultMap;
	private ReadContentByTagName readcontent;
	private ArrayList<String> classifyTagList;

/**
 * 
 * @param classifyTags parameter
 */
	public CalculateTree(String classifyTags) {

		classifyTagList = new ArrayList<String>();
		System.out.println("classfifyTags 123:" + classifyTags);
		readcontent = new ReadContentByTagName();
		// 如果设置了分段的tag，则设置分段的字段列表
		if (!classifyTags.equals("")) {
			String[] classifyArray = classifyTags.split(",");
			for (int i = 0; i < classifyArray.length; i++) {
				classifyTagList.add(classifyArray[i]);
			}
			readcontent.setClassifyTagList(classifyTagList);
		}
	}
/**
 * 
 * @param node parameter
 * @param record parameter
 * @return
 * @throws IOException exception
 */
	public boolean calculateTree(ManyTreeNode node, LogBufferModified record)
			throws IOException {
		// System.out.println("\nIn the calculateTree method!");
		// System.out.println("当前计算节点是：" + node.getData().getNodename());

		ArrayList<ManyTreeNode> childList = node.getChildList();
		ArrayList<Boolean> resultList = new ArrayList<Boolean>();
		resultMap = new HashMap<ManyTreeNode, Boolean>();
		boolean basicOper, result = false;
		int flag = 0; // 一个i节点的所有子孩子结果是否全部得出，如果得出为0，否则为1

		// 1、无孩子，错误的结果
		if (childList.isEmpty()) {
			return false;
		}

		basicOper = true;
		for (ManyTreeNode childnode : childList) {
			if (!childnode.getChildList().isEmpty()) {
				basicOper = false;
			}
		}

		// 2、如果是基本操作符 smaller equal等
		if (basicOper) {
			// System.out.print("BASIC OPER.\t");
			result = calculateOperator(node, record);
			return result;
		}

		// 3、如果是高级操作符and or not等
		for (ManyTreeNode childnode : childList) {
			flag++;
			resultList.add(calculateTree(childnode, record));
		}

		if (flag == childList.size()) {
			// System.out.println("\n孩子节点的值全部算出，计算当前节点值");
			// System.out.println("resultList的值" + resultList);
			result = calculateOperator(node, resultList);
			return result;
		}

		return result;
	}

	/**
	 * 对高级操作符的运算
	 */
	private boolean calculateOperator(ManyTreeNode node, ArrayList<Boolean> list) {
		// System.out.println("\n在计算一级操作符的方法中");
		String nodetype = node.getData().getType();
		if (nodetype.equals("operator")) {
			String operator = node.getData().getNodename();
			// System.out.println("current first operator is:"+operator);
			// 对and的计算
			if (operator.equals(FilterParameter.OPERATOR_AND)) {
				System.out.println("and计算");
				for (Boolean bool : list) {
					// System.out.println("bool值"+bool);
					if (bool) {
						return bool;
					}
				}
				return false;
			}
			// 对or的计算
			if (operator.equals(FilterParameter.OPERATOR_OR)) {
				// System.out.println("or计算");
				for (Boolean bool : list) {
					if (!bool) {
						return bool;
					}
				}
				return true;
			}
			// 对not的计算
			if (operator.equals(FilterParameter.OPERATOR_NOT)) {
				// System.out.println("not计算");
				return !list.get(0);
			}
		}
		System.out.println("规则错误！");
		return true;

	}

	/**
	 * 对二级操作符的计算
	 * 
	 * @param node
	 * @param record
	 * @return
	 */
	private boolean calculateOperator(ManyTreeNode node, LogBufferModified record)
			throws IOException {
		// 是噪音返回true，否则返回false
		ArrayList<ManyTreeNode> childList = node.getChildList();
		String operator = node.getData().getNodename();
		// System.out.println("current operator is: " + operator);

		String tagname = ""; // 字段名称
		String tagvalue = ""; // 字段内容
		String formatvalue = ""; // 字段格式（单串）
		String[] valueList = null; // 字段格式（列表）
		ArrayList<String> valueArray = new ArrayList<String>();

		for (ManyTreeNode cnode : childList) {
			String type = cnode.getData().getType();
			if (type.equals(XMLNode.TAGNAME)) {
				tagname = cnode.getData().getNodename();
				tagvalue = readcontent.getAndCutContentByTagName(tagname,
						record);
			}
			if (type.equals(XMLNode.TAGFORMAT + "0")) {
				formatvalue = cnode.getData().getValue();
			}
			if (type.equals(XMLNode.TAGFORMAT + "1")) {
				if (cnode.getData().getValueList() == null) {
					valueList = null;
				} else if (cnode.getData().getValueList()[0]
						.startsWith("LIST_")) {
					String listFileName = cnode.getData().getValueList()[0]
							.substring("LIST_".length());
					// cnode.getData().setValueList(readStatisticsTXT(listFileName));
					cnode.getData()
							.setValueList(readCassandraTXT(listFileName));
				} else {
					valueList = cnode.getData().getValueList();
					for (int i = 0; i < valueList.length; i++) {
						valueArray.add(valueList[i]);
					}
					// System.out.println("valueArray:"+valueArray);
				}
			}
		}

		/*
		 * 排除没有对应字段的产品，直接返回,是噪音，除Referer之外
		 */
		// System.out.println("tagvalue:\t" + tagvalue);
		if ((tagvalue == null || tagvalue.equals(""))
				&& !tagname.equals("Referer")) {
			return true;
		}

		// 小于
		if (operator.equals(FilterParameter.OPERATOR_SMALLER)) {
			return !(Integer.parseInt(tagvalue) < Integer.parseInt(formatvalue));

		}
		// 大于
		if (operator.equals(FilterParameter.OPERATOR_BIGGER)) {
			return !(Integer.parseInt(tagvalue) > Integer.parseInt(formatvalue));
		}
		// 不大于
		if (operator.equals(FilterParameter.OPERATOR_NOT_BIGGER)) {
			return !(Integer.parseInt(tagvalue) <= Integer.parseInt(formatvalue));
		}
		// 不小于
		if (operator.equals(FilterParameter.OPERATOR_NOT_SMALLER)) {
			// System.out.println("当前操作符：not smaller");
			return !(Integer.parseInt(tagvalue) >= Integer.parseInt(formatvalue));
		}
		// 在....之间
		if (operator.equals(FilterParameter.OPERATOR_BETWEEN)) {

			String substr = formatvalue.substring(1, formatvalue.length() - 1);
			String[] bvaluelist = substr.split(",");
			double from = Double.parseDouble(bvaluelist[0]);
			double to = Double.parseDouble(bvaluelist[1]);
			double value = Double.parseDouble(tagvalue);
			return ((from <= value) && (value <= to));

			/*
			 * if (bvaluelist[0].compareTo(tagvalue) < 0 &&
			 * tagvalue.compareTo(bvaluelist[1]) < 0) { return false; } else if
			 * (bvaluelist[1].compareTo(tagvalue) < 0 &&
			 * tagvalue.compareTo(bvaluelist[0]) < 0) { return false; } else {
			 * return true; }
			 */

		}
		// 不在...之间
		if (operator.equals(FilterParameter.OPERATOR_NOT_BETWEEN)) {

			String substr = formatvalue.substring(1, formatvalue.length() - 1);
			String[] nbvaluelist = substr.split(",");

			if (tagvalue.compareTo(nbvaluelist[0]) < 0
					&& nbvaluelist[0].compareTo(nbvaluelist[1]) <= 0) {
				return false;
			} else {
				return !(nbvaluelist[0].compareTo(nbvaluelist[1]) <= 0
						&& nbvaluelist[1].compareTo(tagvalue) < 0);
			}
			

		}
		// 时间区间（不包含年月日）
		if (operator.equals(FilterParameter.OPERATOR_DURATION)) {

			String substr = formatvalue.substring(1, formatvalue.length() - 1);
			String[] valuelist = substr.split(",");
			String timeValue = tagvalue.substring(8);

			if (valuelist[0].compareTo(timeValue) < 0
					&& timeValue.compareTo(valuelist[1]) < 0) {
				return false;
			}

			return true;
		}
		// 等于
		if (operator.equals(FilterParameter.OPERATOR_EQUAL)) {
		//	System.out.println("获取的值:" + tagvalue + " 要求值为：" + formatvalue);
			return !(tagvalue.compareTo(formatvalue) == 0);
		}

		// 不等于
		if (operator.equals(FilterParameter.OPERATOR_NOT_EQUAL)) {
			return tagvalue.compareTo(formatvalue) == 0;
		}

		// 等于（忽略大小写）
		if (operator.equals(FilterParameter.OPERATOR_EQUAL_WITHOUT_CASE)) {
			// System.out.println("当前操作符：equal without case");
			return !(tagvalue.compareToIgnoreCase(formatvalue) == 0);
		}

		// 不等于（忽略大小写)
		if (operator.equals(FilterParameter.OPERATOR_NOT_EQUAL_WITHOUT_CASE)) {
			// System.out.println("当前操作符：not eaqual without case");
			return tagvalue.compareToIgnoreCase(formatvalue) == 0;
		}

		// 存在与某个列表中，如果存在于其中一个值中，则返回true
		if (operator.equals(FilterParameter.OPERATOR_IN)) {
			return !valueArray.contains(tagvalue);

		}

		// 不存在于某个列表中,如果存在其中任何一个，则返回false
		if (operator.equals(FilterParameter.OPERATOR_NOT_IN)) {
			// System.out.println("当前操作符：not in");
			return valueArray.contains(tagvalue);
		}

		// 存在与某个子串列表，值是一个列表
		if (operator.equals(FilterParameter.OPERATOR_LIKE)) {
			// System.out.println("当前操作符：like");
			Pattern pattern = null;
			Matcher matcher = null;
			int flag = 0; // 默认不存在于此列表
			for (String va : valueArray) {
				pattern = Pattern.compile(va);
				matcher = pattern.matcher(tagvalue);
				if (matcher.matches()) {
					// System.out.println("出现不符合情况的字段" + tagname + "的内容 " +
					// tagvalue + "不符合规则"
					// + formatvalue);
					flag = 1;
				}
			}
			// 没有出现存在于列表中的子串
			return (flag == 0);
		}

		// 不存在某个子串,值是一个列表值
		if (operator.equals(FilterParameter.OPERATOR_NOT_LIKE)) {
			Pattern pattern = null;
			Matcher matcher = null;
			// System.out.println("当前操作符：not like");
			for (String va : valueArray) {
				pattern = Pattern.compile(va);
				matcher = pattern.matcher(tagvalue);

				// 如果匹配，则表示出现了不应该存在的子串
				if (matcher.matches()) {
					// System.out.println("字段值:" + tagvalue + "\t目标值:" + va +
					// "\t匹配");
					// System.out.println("结果为true\n");
					return true;
				}
				// System.out.println("字段值:" + tagvalue + "\t目标值:" + va +
				// "\t不匹配");
			}
			// System.out.println("结果为false\n");
			return false;
		} else {
			return false;
		}
	}

	private String[] readStatisticsTXT(String filename) throws IOException {
		PropertiesReaderServices x1 = PropertiesReaderServicesImpl.instance();
		BufferedReader br = new BufferedReader(new FileReader(
				x1.getProperties("uploadCSVAnalysePath") + filename));
		System.out.println("readfile:" + filename);
		ArrayList<String> temp = new ArrayList<String>();
		String r = br.readLine();
		while (r != null) {
			temp.add(r);
			r = br.readLine();
		}
		String[] list = new String[temp.size()];
		for (int i = 0; i < temp.size(); i++) {
			list[i] = temp.get(i);
		}
		return list;
	}

	private String[] readCassandraTXT(String filename) {
		TreeFileHelper ph = new TreeFileHelper();
		String s = ph.selectTreeFile(filename);
		System.out.println(s);
		String[] list = s.split("\n");
		System.out.println(list.length);
		for (String ss : list) {
			System.out.println(ss);
		}
		return list;
	}
/**
 * 
 * @param args parameter
 */
	public static void main(String[] args) {
		CalculateTree ct = new CalculateTree("");
		ct.readCassandraTXT("23115289657263.txt");
	}
}
